using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using HslCommunication.BasicFramework;

namespace HslCommunication.Controls
{
	/// <summary>
	/// 曲线控件对象
	/// </summary>
	/// <remarks>
	/// 详细参照如下的博客:
	/// </remarks>
	public class UserCurve : UserControl
	{
		private const int value_count_max = 2048;

		private float value_max_left = 100f;

		private float value_min_left = 0f;

		private float value_max_right = 100f;

		private float value_min_right = 0f;

		private int value_Segment = 5;

		private bool value_IsAbscissaStrech = false;

		private int value_StrechDataCountMax = 300;

		private bool value_IsRenderDashLine = true;

		private string textFormat = "HH:mm";

		private int value_IntervalAbscissaText = 100;

		private Random random = null;

		private string value_title = "";

		private int leftRight = 50;

		private int upDowm = 25;

		private Dictionary<string, HslCurveItem> data_list = null;

		private string[] data_text = null;

		private List<AuxiliaryLine> auxiliary_lines;

		private Font font_size9 = null;

		private Font font_size12 = null;

		private Brush brush_deep = null;

		private Pen pen_normal = null;

		private Pen pen_dash = null;

		private Color color_normal = Color.DeepPink;

		private Color color_deep = Color.DimGray;

		private Color color_dash = Color.Gray;

		private StringFormat format_left = null;

		private StringFormat format_right = null;

		private StringFormat format_center = null;

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 获取或设置图形的纵坐标的最大值，该值必须大于最小值
		/// </summary>
		[Category("外观")]
		[Description("获取或设置图形的左纵坐标的最大值，该值必须大于最小值")]
		[Browsable(true)]
		[DefaultValue(100f)]
		public float ValueMaxLeft
		{
			get
			{
				return value_max_left;
			}
			set
			{
				if (value > value_min_left)
				{
					value_max_left = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最小值，该值必须小于最大值
		/// </summary>
		[Category("外观")]
		[Description("获取或设置图形的左纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0f)]
		public float ValueMinLeft
		{
			get
			{
				return value_min_left;
			}
			set
			{
				if (value < value_max_left)
				{
					value_min_left = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最大值，该值必须大于最小值
		/// </summary>
		[Category("外观")]
		[Description("获取或设置图形的右纵坐标的最大值，该值必须大于最小值")]
		[Browsable(true)]
		[DefaultValue(100f)]
		public float ValueMaxRight
		{
			get
			{
				return value_max_right;
			}
			set
			{
				if (value > value_min_right)
				{
					value_max_right = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最小值，该值必须小于最大值
		/// </summary>
		[Category("外观")]
		[Description("获取或设置图形的右纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0f)]
		public float ValueMinRight
		{
			get
			{
				return value_min_right;
			}
			set
			{
				if (value < value_max_right)
				{
					value_min_right = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图形的纵轴分段数
		/// </summary>
		[Category("外观")]
		[Description("获取或设置图形的纵轴分段数")]
		[Browsable(true)]
		[DefaultValue(5)]
		public int ValueSegment
		{
			get
			{
				return value_Segment;
			}
			set
			{
				value_Segment = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置所有的数据是否强制在一个界面里显示
		/// </summary>
		[Category("外观")]
		[Description("获取或设置所有的数据是否强制在一个界面里显示")]
		[Browsable(true)]
		[DefaultValue(false)]
		public bool IsAbscissaStrech
		{
			get
			{
				return value_IsAbscissaStrech;
			}
			set
			{
				value_IsAbscissaStrech = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置拉伸模式下的最大数据量
		/// </summary>
		[Category("外观")]
		[Description("获取或设置拉伸模式下的最大数据量")]
		[Browsable(true)]
		[DefaultValue(300)]
		public int StrechDataCountMax
		{
			get
			{
				return value_StrechDataCountMax;
			}
			set
			{
				value_StrechDataCountMax = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置虚线是否进行显示
		/// </summary>
		[Category("外观")]
		[Description("获取或设置虚线是否进行显示")]
		[Browsable(true)]
		[DefaultValue(true)]
		public bool IsRenderDashLine
		{
			get
			{
				return value_IsRenderDashLine;
			}
			set
			{
				value_IsRenderDashLine = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置坐标轴及相关信息文本的颜色
		/// </summary>
		[Category("外观")]
		[Description("获取或设置坐标轴及相关信息文本的颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "DimGray")]
		public Color ColorLinesAndText
		{
			get
			{
				return color_deep;
			}
			set
			{
				color_deep = value;
				InitializationColor();
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置虚线的颜色
		/// </summary>
		[Category("外观")]
		[Description("获取或设置虚线的颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "Gray")]
		public Color ColorDashLines
		{
			get
			{
				return color_dash;
			}
			set
			{
				color_dash = value;
				pen_dash?.Dispose();
				pen_dash = new Pen(color_dash);
				pen_dash.DashStyle = DashStyle.Custom;
				pen_dash.DashPattern = new float[2]
				{
					5f,
					5f
				};
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置纵向虚线的分隔情况，单位为多少个数据
		/// </summary>
		[Category("外观")]
		[Description("获取或设置纵向虚线的分隔情况，单位为多少个数据")]
		[Browsable(true)]
		[DefaultValue(100)]
		public int IntervalAbscissaText
		{
			get
			{
				return value_IntervalAbscissaText;
			}
			set
			{
				value_IntervalAbscissaText = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置实时数据新增时文本相对应于时间的格式化字符串，默认HH:mm
		/// </summary>
		[Category("外观")]
		[Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串，默认HH:mm")]
		[Browsable(true)]
		[DefaultValue("HH:mm")]
		public string TextAddFormat
		{
			get
			{
				return textFormat;
			}
			set
			{
				textFormat = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置图标的标题信息
		/// </summary>
		[Category("外观")]
		[Description("获取或设置图标的标题信息")]
		[Browsable(true)]
		[DefaultValue("")]
		public string Title
		{
			get
			{
				return value_title;
			}
			set
			{
				value_title = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 实例化一个曲线显示的控件
		/// </summary>
		public UserCurve()
		{
			InitializeComponent();
			DoubleBuffered = true;
			random = new Random();
			data_list = new Dictionary<string, HslCurveItem>();
			auxiliary_lines = new List<AuxiliaryLine>();
			format_left = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Near
			};
			format_right = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Far
			};
			format_center = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Center
			};
			font_size9 = new Font("宋体", 9f);
			font_size12 = new Font("宋体", 12f);
			InitializationColor();
			pen_dash = new Pen(color_deep);
			pen_dash.DashStyle = DashStyle.Custom;
			pen_dash.DashPattern = new float[2]
			{
				5f,
				5f
			};
		}

		private void InitializationColor()
		{
			pen_normal?.Dispose();
			brush_deep?.Dispose();
			pen_normal = new Pen(color_deep);
			brush_deep = new SolidBrush(color_deep);
		}

		/// <summary>
		/// 设置曲线的横坐标文本，适用于显示一些固定的曲线信息
		/// </summary>
		/// <param name="descriptions">应该和曲线的点数一致</param>
		public void SetCurveText(string[] descriptions)
		{
			data_text = descriptions;
			Invalidate();
		}

		/// <summary>
		/// 新增或修改一条指定关键字的左参考系曲线数据，需要指定数据，颜色随机，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data">曲线的具体数据</param>
		public void SetLeftCurve(string key, float[] data)
		{
			SetLeftCurve(key, data, Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
		}

		/// <summary>
		/// 新增或修改一条指定关键字的左参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data"></param>
		/// <param name="lineColor"></param>
		public void SetLeftCurve(string key, float[] data, Color lineColor)
		{
			SetCurve(key, isLeft: true, data, lineColor, 1f);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的右参考系曲线数据，需要指定数据，颜色随机，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data"></param>
		public void SetRightCurve(string key, float[] data)
		{
			SetRightCurve(key, data, Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
		}

		/// <summary>
		/// 新增或修改一条指定关键字的右参考系曲线数据，需要指定数据，颜色，没有数据上限，线条宽度为1
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="data"></param>
		/// <param name="lineColor"></param>
		public void SetRightCurve(string key, float[] data, Color lineColor)
		{
			SetCurve(key, isLeft: false, data, lineColor, 1f);
		}

		/// <summary>
		/// 新增或修改一条指定关键字的曲线数据，需要指定参考系及数据，颜色，线条宽度
		/// </summary>
		/// <param name="key">曲线关键字</param>
		/// <param name="isLeft">是否以左侧坐标轴为参照系</param>
		/// <param name="data">数据</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="thickness">线条宽度</param>
		public void SetCurve(string key, bool isLeft, float[] data, Color lineColor, float thickness)
		{
			if (data_list.ContainsKey(key))
			{
				if (data == null)
				{
					data = new float[0];
				}
				data_list[key].Data = data;
			}
			else
			{
				if (data == null)
				{
					data = new float[0];
				}
				data_list.Add(key, new HslCurveItem
				{
					Data = data,
					LineThickness = thickness,
					LineColor = lineColor,
					IsLeftFrame = isLeft
				});
				if (data_text == null)
				{
					data_text = new string[data.Length];
				}
			}
			Invalidate();
		}

		/// <summary>
		/// 移除指定关键字的曲线
		/// </summary>
		/// <param name="key">曲线关键字</param>
		public void RemoveCurve(string key)
		{
			if (data_list.ContainsKey(key))
			{
				data_list.Remove(key);
			}
			if (data_list.Count == 0)
			{
				data_text = new string[0];
			}
			Invalidate();
		}

		/// <summary>
		/// 移除指定关键字的曲线
		/// </summary>
		public void RemoveAllCurve()
		{
			int count = data_list.Count;
			data_list.Clear();
			if (data_list.Count == 0)
			{
				data_text = new string[0];
			}
			if (count > 0)
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 新增指定关键字曲线的一个数据，注意该关键字的曲线必须存在，否则无效
		/// </summary>
		/// <param name="key">新增曲线的关键字</param>
		/// <param name="values"></param>
		/// <param name="isUpdateUI">是否刷新界面</param>
		private void AddCurveData(string key, float[] values, bool isUpdateUI)
		{
			if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
			{
				return;
			}
			HslCurveItem hslCurveItem = data_list[key];
			if (hslCurveItem.Data != null)
			{
				if (value_IsAbscissaStrech)
				{
					SoftBasic.AddArrayData(ref hslCurveItem.Data, values, value_StrechDataCountMax);
				}
				else
				{
					SoftBasic.AddArrayData(ref hslCurveItem.Data, values, 2048);
				}
				if (isUpdateUI)
				{
					Invalidate();
				}
			}
		}

		private void AddCurveTime(int count)
		{
			if (data_text != null)
			{
				string[] array = new string[count];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = DateTime.Now.ToString(textFormat);
				}
				if (value_IsAbscissaStrech)
				{
					SoftBasic.AddArrayData(ref data_text, array, value_StrechDataCountMax);
				}
				else
				{
					SoftBasic.AddArrayData(ref data_text, array, 2048);
				}
			}
		}

		/// <summary>
		/// 新增指定关键字曲线的一个数据，注意该关键字的曲线必须存在，否则无效
		/// </summary>
		/// <param name="key">曲线的关键字</param>
		/// <param name="value">数据值</param>
		public void AddCurveData(string key, float value)
		{
			AddCurveData(key, new float[1]
			{
				value
			});
		}

		/// <summary>
		/// 新增指定关键字曲线的一组数据，注意该关键字的曲线必须存在，否则无效
		/// </summary>
		/// <param name="key">曲线的关键字</param>
		/// <param name="values">数组值</param>
		public void AddCurveData(string key, float[] values)
		{
			AddCurveData(key, values, isUpdateUI: false);
			if (values != null && values.Length != 0)
			{
				AddCurveTime(values.Length);
			}
			Invalidate();
		}

		/// <summary>
		/// 新增指定关键字数组曲线的一组数据，注意该关键字的曲线必须存在，否则无效，一个数据对应一个数组
		/// </summary>
		/// <param name="keys">曲线的关键字数组</param>
		/// <param name="values">数组值</param>
		public void AddCurveData(string[] keys, float[] values)
		{
			if (keys == null)
			{
				throw new ArgumentNullException("keys");
			}
			if (values == null)
			{
				throw new ArgumentNullException("values");
			}
			if (keys.Length != values.Length)
			{
				throw new Exception("两个参数的数组长度不一致。");
			}
			for (int i = 0; i < keys.Length; i++)
			{
				AddCurveData(keys[i], new float[1]
				{
					values[i]
				}, isUpdateUI: false);
			}
			AddCurveTime(1);
			Invalidate();
		}

		/// <summary>
		/// 设置一条曲线是否是可见的，如果该曲线不存在，则无效。
		/// </summary>
		/// <param name="key">关键字</param>
		/// <param name="visible">是否可见</param>
		public void SetCurveVisible(string key, bool visible)
		{
			if (data_list.ContainsKey(key))
			{
				HslCurveItem hslCurveItem = data_list[key];
				hslCurveItem.Visible = visible;
				Invalidate();
			}
		}

		/// <summary>
		/// 设置多条曲线是否是可见的，如果该曲线不存在，则无效。
		/// </summary>
		/// <param name="keys">关键字</param>
		/// <param name="visible">是否可见</param>
		public void SetCurveVisible(string[] keys, bool visible)
		{
			foreach (string key in keys)
			{
				if (data_list.ContainsKey(key))
				{
					HslCurveItem hslCurveItem = data_list[key];
					hslCurveItem.Visible = visible;
				}
			}
			Invalidate();
		}

		/// <summary>
		/// 新增一条左侧的辅助线，使用默认的文本颜色
		/// </summary>
		/// <param name="value">数据值</param>
		public void AddLeftAuxiliary(float value)
		{
			AddLeftAuxiliary(value, ColorLinesAndText);
		}

		/// <summary>
		/// 新增一条左侧的辅助线，使用指定的颜色
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		public void AddLeftAuxiliary(float value, Color lineColor)
		{
			AddLeftAuxiliary(value, lineColor, 1f);
		}

		/// <summary>
		/// 新增一条左侧的辅助线
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="lineThickness">线条宽度</param>
		public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness)
		{
			AddAuxiliary(value, lineColor, lineThickness, isLeft: true);
		}

		/// <summary>
		/// 新增一条右侧的辅助线，使用默认的文本颜色
		/// </summary>
		/// <param name="value">数据值</param>
		public void AddRightAuxiliary(float value)
		{
			AddRightAuxiliary(value, ColorLinesAndText);
		}

		/// <summary>
		/// 新增一条右侧的辅助线，使用指定的颜色
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		public void AddRightAuxiliary(float value, Color lineColor)
		{
			AddRightAuxiliary(value, lineColor, 1f);
		}

		/// <summary>
		/// 新增一条右侧的辅助线
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="lineThickness">线条宽度</param>
		public void AddRightAuxiliary(float value, Color lineColor, float lineThickness)
		{
			AddAuxiliary(value, lineColor, lineThickness, isLeft: false);
		}

		private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isLeft)
		{
			auxiliary_lines.Add(new AuxiliaryLine
			{
				Value = value,
				LineColor = lineColor,
				PenDash = new Pen(lineColor)
				{
					DashStyle = DashStyle.Custom,
					DashPattern = new float[2]
					{
						5f,
						5f
					}
				},
				IsLeftFrame = isLeft,
				LineThickness = lineThickness,
				LineTextBrush = new SolidBrush(lineColor)
			});
			Invalidate();
		}

		/// <summary>
		/// 移除所有的指定值的辅助曲线，包括左边的和右边的
		/// </summary>
		/// <param name="value"></param>
		public void RemoveAuxiliary(float value)
		{
			int num = 0;
			for (int num2 = auxiliary_lines.Count - 1; num2 >= 0; num2--)
			{
				if (auxiliary_lines[num2].Value == value)
				{
					auxiliary_lines[num2].Dispose();
					auxiliary_lines.RemoveAt(num2);
					num++;
				}
			}
			if (num > 0)
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 移除所有的辅助线
		/// </summary>
		public void RemoveAllAuxiliary()
		{
			int count = auxiliary_lines.Count;
			auxiliary_lines.Clear();
			if (count > 0)
			{
				Invalidate();
			}
		}

		private void UserCurve_Paint(object sender, PaintEventArgs e)
		{
			if (!Authorization.nzugaydgwadawdibbas())
			{
				return;
			}
			Graphics graphics = e.Graphics;
			graphics.SmoothingMode = SmoothingMode.HighQuality;
			graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			if (BackColor != Color.Transparent)
			{
				graphics.Clear(BackColor);
			}
			int width = base.Width;
			int height = base.Height;
			if (width < 120 || height < 60)
			{
				return;
			}
			graphics.DrawLines(pen_normal, new Point[4]
			{
				new Point(leftRight - 1, upDowm - 8),
				new Point(leftRight - 1, height - upDowm),
				new Point(width - leftRight, height - upDowm),
				new Point(width - leftRight, upDowm - 8)
			});
			if (!string.IsNullOrEmpty(value_title))
			{
				graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
			}
			SoftPainting.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
			SoftPainting.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (auxiliary_lines[i].IsLeftFrame)
				{
					auxiliary_lines[i].PaintValue = SoftPainting.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[i].Value) + (float)upDowm;
				}
				else
				{
					auxiliary_lines[i].PaintValue = SoftPainting.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[i].Value) + (float)upDowm;
				}
			}
			for (int j = 0; j <= value_Segment; j++)
			{
				float value = (float)j * (value_max_left - value_min_left) / (float)value_Segment + value_min_left;
				float num = SoftPainting.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
				if (IsNeedPaintDash(num))
				{
					graphics.DrawLine(pen_normal, leftRight - 4, num, leftRight - 1, num);
					RectangleF layoutRectangle = new RectangleF(0f, num - 9f, leftRight - 4, 20f);
					graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
					float num2 = (float)j * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
					graphics.DrawLine(pen_normal, width - leftRight + 1, num, width - leftRight + 4, num);
					layoutRectangle.Location = new PointF(width - leftRight + 4, num - 9f);
					graphics.DrawString(num2.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
					if (j > 0 && value_IsRenderDashLine)
					{
						graphics.DrawLine(pen_dash, leftRight, num, width - leftRight, num);
					}
				}
			}
			if (value_IsRenderDashLine)
			{
				if (value_IsAbscissaStrech)
				{
					float num3 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
					int num4 = CalculateDataCountByOffect(num3);
					for (int k = 0; k < value_StrechDataCountMax; k += num4)
					{
						if (k > 0 && k < value_StrechDataCountMax - 1)
						{
							graphics.DrawLine(pen_dash, (float)k * num3 + (float)leftRight, upDowm, (float)k * num3 + (float)leftRight, height - upDowm - 1);
						}
						if (data_text != null && k < data_text.Length && (float)k * num3 + (float)leftRight < (float)(data_text.Length - 1) * num3 + (float)leftRight - 40f)
						{
							graphics.DrawString(layoutRectangle: new Rectangle((int)((float)k * num3), height - upDowm + 1, 100, upDowm), s: data_text[k], font: font_size9, brush: brush_deep, format: format_center);
						}
					}
					string[] array = data_text;
					if (array != null && array.Length > 1)
					{
						if (data_text.Length < value_StrechDataCountMax)
						{
							graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num3 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num3 + (float)leftRight, height - upDowm - 1);
						}
						graphics.DrawString(layoutRectangle: new Rectangle((int)((float)(data_text.Length - 1) * num3 + (float)leftRight) - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
					}
				}
				else
				{
					int num5 = width - 2 * leftRight + 1;
					for (int l = leftRight; l < width - leftRight; l += value_IntervalAbscissaText)
					{
						if (l != leftRight)
						{
							graphics.DrawLine(pen_dash, l, upDowm, l, height - upDowm - 1);
						}
						if (data_text == null)
						{
							continue;
						}
						int num6 = (num5 > data_text.Length) ? data_text.Length : num5;
						if (l - leftRight < data_text.Length && num6 - (l - leftRight) > 40)
						{
							if (data_text.Length <= num5)
							{
								graphics.DrawString(layoutRectangle: new Rectangle(l - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[l - leftRight], font: font_size9, brush: brush_deep, format: format_center);
								continue;
							}
							graphics.DrawString(layoutRectangle: new Rectangle(l - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[l - leftRight + data_text.Length - num5], font: font_size9, brush: brush_deep, format: format_center);
						}
					}
					string[] array2 = data_text;
					if (array2 != null && array2.Length > 1)
					{
						if (data_text.Length >= num5)
						{
							graphics.DrawString(layoutRectangle: new Rectangle(width - leftRight - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
						}
						else
						{
							graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
							graphics.DrawString(layoutRectangle: new Rectangle(data_text.Length + leftRight - 1 - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
						}
					}
				}
			}
			for (int m = 0; m < auxiliary_lines.Count; m++)
			{
				if (auxiliary_lines[m].IsLeftFrame)
				{
					graphics.DrawLine(auxiliary_lines[m].PenDash, leftRight - 4, auxiliary_lines[m].PaintValue, leftRight - 1, auxiliary_lines[m].PaintValue);
					graphics.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[m].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[m].Value.ToString(), font: font_size9, brush: auxiliary_lines[m].LineTextBrush, format: format_right);
				}
				else
				{
					graphics.DrawLine(auxiliary_lines[m].PenDash, width - leftRight + 1, auxiliary_lines[m].PaintValue, width - leftRight + 4, auxiliary_lines[m].PaintValue);
					graphics.DrawString(layoutRectangle: new RectangleF(width - leftRight + 4, auxiliary_lines[m].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[m].Value.ToString(), font: font_size9, brush: auxiliary_lines[m].LineTextBrush, format: format_left);
				}
				graphics.DrawLine(auxiliary_lines[m].PenDash, leftRight, auxiliary_lines[m].PaintValue, width - leftRight, auxiliary_lines[m].PaintValue);
			}
			if (value_IsAbscissaStrech)
			{
				foreach (HslCurveItem value2 in data_list.Values)
				{
					if (!value2.Visible)
					{
						continue;
					}
					float[] data = value2.Data;
					if (data != null && data.Length > 1)
					{
						float num7 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
						PointF[] array3 = new PointF[value2.Data.Length];
						for (int n = 0; n < value2.Data.Length; n++)
						{
							array3[n].X = (float)leftRight + (float)n * num7;
							array3[n].Y = SoftPainting.ComputePaintLocationY(value2.IsLeftFrame ? value_max_left : value_max_right, value2.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value2.Data[n]) + (float)upDowm;
						}
						using Pen pen = new Pen(value2.LineColor, value2.LineThickness);
						graphics.DrawLines(pen, array3);
					}
				}
				return;
			}
			foreach (HslCurveItem value3 in data_list.Values)
			{
				if (!value3.Visible)
				{
					continue;
				}
				float[] data2 = value3.Data;
				if (data2 == null || data2.Length <= 1)
				{
					continue;
				}
				int num8 = width - 2 * leftRight + 1;
				PointF[] array4;
				if (value3.Data.Length <= num8)
				{
					array4 = new PointF[value3.Data.Length];
					for (int num9 = 0; num9 < value3.Data.Length; num9++)
					{
						array4[num9].X = leftRight + num9;
						array4[num9].Y = SoftPainting.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num9]) + (float)upDowm;
					}
				}
				else
				{
					array4 = new PointF[num8];
					for (int num10 = 0; num10 < array4.Length; num10++)
					{
						array4[num10].X = leftRight + num10;
						array4[num10].Y = SoftPainting.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num10 + value3.Data.Length - num8]) + (float)upDowm;
					}
				}
				using Pen pen2 = new Pen(value3.LineColor, value3.LineThickness);
				graphics.DrawLines(pen2, array4);
			}
		}

		private bool IsNeedPaintDash(float paintValue)
		{
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
				{
					return false;
				}
			}
			return true;
		}

		private int CalculateDataCountByOffect(float offect)
		{
			if (offect > 40f)
			{
				return 1;
			}
			offect = 40f / offect;
			return (int)Math.Ceiling(offect);
		}

		private void UserCurve_SizeChanged(object sender, EventArgs e)
		{
			Invalidate();
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 12f);
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
			BackColor = System.Drawing.Color.Transparent;
			base.Name = "UserCurve";
			base.Size = new System.Drawing.Size(615, 296);
			base.SizeChanged += new System.EventHandler(UserCurve_SizeChanged);
			base.Paint += new System.Windows.Forms.PaintEventHandler(UserCurve_Paint);
			ResumeLayout(false);
		}
	}
}
